package com.itcoon.cloud.framework.webmvc.exception.handler;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.itcoon.cloud.framework.webmvc.response.ApiResponse;
import com.itcoon.cloud.framework.webmvc.utils.ApiResponseUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestClientResponseException;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

public class RestResponseErrHandler extends DefaultResponseErrorHandler {

    private static final Logger log = LoggerFactory.getLogger(RestResponseErrHandler.class);

    private final ObjectMapper objectMapper;

    public RestResponseErrHandler(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    @Override
    protected void handleError(ClientHttpResponse response, HttpStatus statusCode) throws IOException {
        switch (statusCode.series()){
            case CLIENT_ERROR:
                log.error("Request Error: status code is {}", statusCode.value());
                throw new RuntimeException("rest request error");
            case SERVER_ERROR:
                log.error("Remote response Error: status code is {}", statusCode.value());
                byte[] body = this.getResponseBody(response);
                ApiResponse apiResponse = null;
                try {
                    apiResponse = objectMapper.readValue(body, ApiResponse.class);
                }catch (IOException e){
                    throw new RestClientResponseException("Remote response Error", statusCode.value(), response.getStatusText(), response.getHeaders(), body, StandardCharsets.UTF_8);
                }
                String code = apiResponse.getCode();
                try{
                    int codeNum = Integer.parseInt(code);
                    log.error("raise remote business response  error: errorCode is {}", codeNum);
                    ApiResponseUtils.writeJsonResponse(apiResponse, statusCode.value());
                }catch (NumberFormatException e){
                    log.error("Remote response Error: response is {}", response.getBody());
                    throw new RuntimeException("remote response error");
                }
            default:
        }
    }
}
